﻿// day05-SyncServer.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <cstdlib>
#include <iostream>
#include <boost/asio.hpp>
#include <set>
using boost::asio::ip::tcp;

// 定义最大接收数据长度
const int max_length = 1024;
// 定义socket智能指针类型
typedef std::shared_ptr<tcp::socket> socket_ptr;
// 存储所有创建的线程
std::set<std::shared_ptr<std::thread>> thread_set;
using namespace std;

// 处理单个客户端连接的会话函数
void session(socket_ptr sock)
{
    try
    {
        for (;;)
        {
            char data[max_length];
            memset(data, '\0', max_length); // 清空接收缓冲区
            boost::system::error_code error;
            // 从socket读取数据
            size_t length = sock->read_some(boost::asio::buffer(data, max_length), error);

            // 处理连接断开的情况
            if (error == boost::asio::error::eof)
            {
                std::cout << "connection closed by peer" << endl;
                break;
            }
            else if (error)
            {
                throw boost::system::system_error(error);
            }

            // 打印接收到的信息
            cout << "receive from " << sock->remote_endpoint().address().to_string() << endl;

            // memcpy(data + length, "hello", 6);

            cout << "receive length is " << length << endl;
            cout << "receive message is " << data << endl;
            // 将接收到的数据回传给客户端（echo服务器）
            boost::asio::write(*sock, boost::asio::buffer(data, length + 6));
        }
    }
    catch (std::exception &e)
    {
        std::cerr << "Exception in thread: " << e.what() << "\n"
                  << std::endl;
    }
}

// 服务器主函数，负责接受新的客户端连接
void server(boost::asio::io_context &io_context, unsigned short port)
{
    // 创建接受器，监听指定端口
    tcp::acceptor a(io_context, tcp::endpoint(tcp::v4(), port));
    for (;;)
    {
        // 为新连接创建socket
        socket_ptr socket(new tcp::socket(io_context));
        // 等待并接受新的连接
        a.accept(*socket);
        // 为新连接创建独立的线程处理
        auto t = std::make_shared<std::thread>(session, socket);
        thread_set.insert(t);
    }
}

// 程序入口函数
int main()
{
    try
    {
        // 创建io上下文
        boost::asio::io_context ioc;
        // 启动服务器，监听10086端口
        server(ioc, 10086);
        // 等待所有工作线程完成
        for (auto &t : thread_set)
        {
            t->join();
        }
    }
    catch (std::exception &e)
    {
        std::cerr << "Exception " << e.what() << "\n";
    }
    return 0;
}
